package com.ruoyi.HKISAPI.service.Impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.ruoyi.HKISAPI.controller.ImageDownloader;
import com.ruoyi.HKISAPI.service.ISAPIService;
import com.ruoyi.rsikManage.domain.MonitorPoint;
import com.ruoyi.rsikManage.domain.TVcrData;
import com.ruoyi.rsikManage.mapper.TVcrDataMapper;
import org.apache.http.HttpEntity;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class ISAPIServiceImpl implements ISAPIService {

    private static TVcrDataMapper tVcrDataMapper;

    private static ImageDownloader imageDownloader;

    @Autowired
    public void setLoader(ImageDownloader imageDownloader,
                                   TVcrDataMapper tVcrDataMapper) {
        ISAPIServiceImpl.imageDownloader = imageDownloader;
        ISAPIServiceImpl.tVcrDataMapper = tVcrDataMapper;
    }

    //
    @Override
    public Map<String,Object> getChannels() {
        Map<String,Object> data = new HashMap<>();

        TVcrData tVcrData = new TVcrData();
        String url = "";
        String url2 = "";
        List<TVcrData> tVcrDataList = tVcrDataMapper.selectTVcrDataList(tVcrData);
        List<MonitorPoint> allMonitorPoints = new ArrayList<>();
        List<Map> JsonMapList = new ArrayList<>();
        List<Map> JsonMapList2 = new ArrayList<>();

        for(TVcrData vcr:tVcrDataList){
            Map<String,Object> result = new HashMap<>();

            String vcrIp = vcr.getVcrIp();
            String vcrPort = vcr.getVcrPort();
            String vcrUsername = vcr.getVcrUsername();
            String vcrPassword = vcr.getVcrPassword();
            String vcrName = vcr.getVcrName();

            String responseData =null;
            String responseData2 =null;

            url = "http://"+vcrIp+":"+vcrPort+"/ISAPI/ContentMgmt/InputProxy/channels";
            url2 = "http://"+vcrIp+":"+vcrPort+"/ISAPI/ContentMgmt/InputProxy/channels/status";

            try{
                responseData= performGetRequest(url, vcrUsername, vcrPassword);
                responseData2= performGetRequest(url2, vcrUsername, vcrPassword);
//                System.out.println(responseData);
//                System.out.println(responseData2);
                Map<String, Object> resultMap = convertXmlToJsonMap(responseData);
                Map<String, Object> resultMap2 = convertXmlToJsonMap(responseData2);

                List<MonitorPoint> monitorPoints = new ArrayList<>();
                List<Map<String,Object>> InputProxyChannel = (List<Map<String,Object>>)resultMap.get("InputProxyChannel");
                List<Map<String,Object>> InputProxyChannelStatus = (List<Map<String,Object>>)resultMap2.get("InputProxyChannelStatus");
                if (InputProxyChannel!=null&&InputProxyChannel.size()>0){


                for (int i = 0; i < InputProxyChannel.size(); i++) {
                    // 获取当前通道的源输入端口描述符
                    Map<String, Object> sourceInputPortDescriptor = (Map<String, Object>) InputProxyChannel.get(i).get("sourceInputPortDescriptor");
                    // 获取对应的状态信息
                    String online = (String) InputProxyChannelStatus.get(i).get("online"); // 确保这里也使用i来获取对应状态
                    // 创建一个新的映射来保存更新后的值，包括原有的键值对和新的"online"状态
                    String id = (String)InputProxyChannel.get(i).get("id");
                    String name = (String)InputProxyChannel.get(i).get("name");
                    Map<String, Object> updatedMap = new HashMap<>(InputProxyChannel.get(i));
                    String ipAddress = (String)sourceInputPortDescriptor.get("ipAddress");
                    String proxyProtocol = (String)sourceInputPortDescriptor.get("proxyProtocol");
                    String managePortNo = (String)sourceInputPortDescriptor.get("managePortNo");
                    String srcInputPort = (String)sourceInputPortDescriptor.get("srcInputPort");
                    String userName = (String)sourceInputPortDescriptor.get("userName");
                    String streamType = (String)sourceInputPortDescriptor.get("streamType");
                    String deviceID = (String)sourceInputPortDescriptor.get("deviceID");

                    updatedMap.put("id", id);
                    updatedMap.put("online", online);
                    updatedMap.put("ipAddress", ipAddress);
                    updatedMap.put("proxyProtocol", proxyProtocol);
                    updatedMap.put("managePortNo", managePortNo);
                    updatedMap.put("srcInputPort", srcInputPort);
                    updatedMap.put("userName", userName);
                    updatedMap.put("streamType", streamType);
                    updatedMap.put("deviceID", deviceID);
                    // 使用更新后的映射替换原列表中的映射
                    InputProxyChannel.set(i, updatedMap);
                    MonitorPoint monitorPoint = new MonitorPoint();
                    monitorPoint.setIdx(id);
                    //将IP地址字符串转换为每段数字不足三位时前面补0的形式
                    String apeId = convertIpToNumeric(ipAddress);
                    monitorPoint.setApeId(apeId);
                    monitorPoint.setOwnerApsIp(vcrIp);
                    monitorPoint.setName(name);
                    monitorPoint.setResourceType(ipAddress);
                    monitorPoint.setOwnerApsName(vcrName);
                    String isOnline;
                    if ("true".equals(online)){
                        isOnline="1";
                    }else {
                        isOnline="2";
                    }
                    monitorPoint.setIsOnline(isOnline);

                    monitorPoints.add(monitorPoint);
                    allMonitorPoints.add(monitorPoint);
                }

                }


//            List<MonitorPoint> list = toMonitorList(monitorListJsonStr);
                JsonMapList.add(resultMap);
                JsonMapList2.add(resultMap2);
//
//                System.out.println("Result Map2: " + resultMap2);
                result.put("responseData",responseData);
                result.put("responseData2",responseData2);
                result.put("monitorPoints",monitorPoints);


            }catch (IOException e) {
                e.printStackTrace();
                continue;
            }
        }
        //
        data.put("monitorPoints",allMonitorPoints);
        data.put("JsonMapList",JsonMapList);
        data.put("JsonMapList2",JsonMapList2);

        return data;
    }
    //
    @Override
    public Map<String, Object> getHKTESTMap() {
        Map<String,Object> data = new HashMap<>();

        TVcrData tVcrData = new TVcrData();
        String url = "";
        String url2 = "";
        String url3 = "";

        List<TVcrData> tVcrDataList = tVcrDataMapper.selectTVcrDataList(tVcrData);
        List<MonitorPoint> allMonitorPoints = new ArrayList<>();
        List<Map> JsonMapList = new ArrayList<>();
        List<Map> JsonMapList2 = new ArrayList<>();

//        for(TVcrData vcr:tVcrDataList){
            Map<String,Object> result = new HashMap<>();

            String vcrIp = "192.168.7.50";
            String vcrPort = "80";
            String vcrUsername = "admin";
            String vcrPassword = "sxygsj123";
            String vcrName = "";

            String responseData =null;
            String responseData2 =null;

            url = "http://"+vcrIp+":"+vcrPort+"/ISAPI/Event/notification/subscribeEventCap";
            url2 = "http://"+vcrIp+":"+vcrPort+"/ISAPI/Event/notification/alertStream";
            url3 = "http://"+vcrIp+":"+vcrPort+"/ISAPI/Event/notification/subscribeEvent";

            try{
//                responseData= performGetRequest(url, vcrUsername, vcrPassword);
//                responseData2= performGetRequest(url2, vcrUsername, vcrPassword);

                responseData= performGetRequest2(url3, vcrUsername, vcrPassword);
//                responseData2= performGetRequest(url2, vcrUsername, vcrPassword);
                Map<String, Object> resultMap = convertXmlToJsonMap(responseData);
                Map<String, Object> resultMap2 = convertXmlToJsonMap(responseData2);

                List<MonitorPoint> monitorPoints = new ArrayList<>();
                List<Map<String,Object>> InputProxyChannel = (List<Map<String,Object>>)resultMap.get("InputProxyChannel");
                List<Map<String,Object>> InputProxyChannelStatus = (List<Map<String,Object>>)resultMap2.get("InputProxyChannelStatus");

                JsonMapList.add(resultMap);
                JsonMapList2.add(resultMap2);
//
//                System.out.println("Result Map: " + resultMap);
//                System.out.println("Result Map2: " + resultMap2);
                result.put("responseData",responseData);
                result.put("responseData2",responseData2);
                result.put("monitorPoints",monitorPoints);


            }catch (IOException e) {
                e.printStackTrace();

            }
//        }

        data.put("monitorPoints",allMonitorPoints);
        data.put("JsonMapList",JsonMapList);
        data.put("JsonMapList2",JsonMapList2);
        data.put("responseData",responseData);
        data.put("responseData2",responseData2);
        return data;
    }

    @Override
    public Map<String, Object> getContentMgmt() {
        {
            Map<String,Object> data = new HashMap<>();

            TVcrData tVcrData = new TVcrData();
            String url = "";
            String url2 = "";
            String url3 = "";

            List<TVcrData> tVcrDataList = tVcrDataMapper.selectTVcrDataList(tVcrData);
            List<MonitorPoint> allMonitorPoints = new ArrayList<>();
            List<Map> JsonMapList = new ArrayList<>();
            List<Map> JsonMapList2 = new ArrayList<>();

//        for(TVcrData vcr:tVcrDataList){
            Map<String,Object> result = new HashMap<>();

            String vcrIp = "192.168.7.50";
            String vcrPort = "80";
            String vcrUsername = "admin";
            String vcrPassword = "sxygsj123";
            String vcrName = "";

            String responseData =null;
            String responseData2 =null;

            url = "http://"+vcrIp+":"+vcrPort+"/ISAPI/Event/notification/subscribeEventCap";
            url2 = "http://"+vcrIp+":"+vcrPort+"/ISAPI/Event/notification/alertStream";
            url3 = "http://"+vcrIp+":"+vcrPort+"/ISAPI/ContentMgmt/search";

            try{
//                responseData= performGetRequest(url, vcrUsername, vcrPassword);
//                responseData2= performGetRequest(url2, vcrUsername, vcrPassword);

                responseData= performGetRequest3(url3, vcrUsername, vcrPassword);
//                responseData2= performGetRequest(url2, vcrUsername, vcrPassword);
                Map<String, Object> resultMap = convertXmlToJsonMap(responseData);
                Map<String, Object> resultMap2 = convertXmlToJsonMap(responseData2);

                List<MonitorPoint> monitorPoints = new ArrayList<>();
                List<Map<String,Object>> InputProxyChannel = (List<Map<String,Object>>)resultMap.get("InputProxyChannel");
                List<Map<String,Object>> InputProxyChannelStatus = (List<Map<String,Object>>)resultMap2.get("InputProxyChannelStatus");

                JsonMapList.add(resultMap);
                JsonMapList2.add(resultMap2);
//
//                System.out.println("Result Map: " + resultMap);
//                System.out.println("Result Map2: " + resultMap2);
                result.put("responseData",responseData);
                result.put("responseData2",responseData2);
                result.put("monitorPoints",monitorPoints);


            }catch (IOException e) {
                e.printStackTrace();

            }
//        }

            data.put("monitorPoints",allMonitorPoints);
            data.put("JsonMapList",JsonMapList);
            data.put("JsonMapList2",JsonMapList2);
            data.put("responseData",responseData);
            data.put("responseData2",responseData2);
            return data;
        }
    }

    @Override
    public Map<String, Object> downloadImageWithDigestAuth(String imageUrl, String username, String password, String localFilePath) {
        try {
            imageDownloader.downloadImageWithDigestAuth(imageUrl,username,password,localFilePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new HashMap<>();
    }

    public static void main(String[] args) {
        String url = "http://192.168.18.84:80/ISAPI/System/deviceInfo";
        String username = "admin";
        String password = "admin12345";

        try {
            String responseData = performGetRequest(url, username, password);
            System.out.println("Response Data:");
            System.out.println(responseData);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String performGetRequest(String url, String username, String password) throws IOException {
        // 创建凭据提供程序并设置用户名和密码
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));

        // 创建 HttpClient 实例
        try (CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCredentialsProvider(credsProvider)
                .build()) {

            // 创建 GET 请求
            HttpGet httpGet = new HttpGet(url);
            httpGet.setHeader("Accept", "application/json"); // 设置请求头

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                // 处理响应
                int statusCode = response.getStatusLine().getStatusCode();
                HttpEntity entity = response.getEntity();
                System.out.println(entity);
                if (entity != null) {
                    return EntityUtils.toString(entity, "UTF-8");
                }
            }
        }
        return null;
    }

    public static String performGetRequest2(String url, String username, String password) throws IOException {
        // 创建凭据提供程序并设置用户名和密码
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));

        // 创建 HttpClient 实例
        try (CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCredentialsProvider(credsProvider)
                .build()) {

            // 创建HttpPost请求
            HttpPost httpPost = new HttpPost(url);

            // 设置请求头
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Connection", "keep-alive");
            // 如果有需要，还可以添加更多头部信息，如Content-Type等

            // 执行请求
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                // 处理响应
                int statusCode = response.getStatusLine().getStatusCode();
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    return EntityUtils.toString(entity, "UTF-8");
                }
            }
        }
        return null;
    }

    public static String performGetRequest3(String url, String username, String password) throws IOException {


            // 创建凭据提供程序并设置用户名和密码
            CredentialsProvider credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));

            // 创建 HttpClient 实例
            try (CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultCredentialsProvider(credsProvider)
                    .build()) {

                // 创建HttpPost请求
                HttpPost httpPost = new HttpPost(url);

                // 设置请求头
                httpPost.setHeader("Connection", "keep-alive");
                httpPost.setHeader("Content-Length", "486");
                httpPost.setHeader("Cache-Control", "max-age=0");
                httpPost.setHeader("Accept", "*/*");
                httpPost.setHeader("X-Requested-With", "XMLHttpRequest");
                httpPost.setHeader("If-Modified-Since", "0");
                httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
                httpPost.setHeader("Accept-Encoding", "gzip, deflate");
                httpPost.setHeader("Accept-Language", "zh-CN,zh;q=0.9");

                // 设置请求体
                StringEntity requestEntity = new StringEntity(
                        "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                                "<CMSearchDescription>\n" +
                                "    <searchID>88C2CD4D-D3FA-4AD4-BD80-555C18205DCC</searchID>\n" +
                                "    <trackList>\n" +
                                "        <trackID>101</trackID>\n" +
                                "    </trackList>\n" +
                                "    <timeSpanList>\n" +
                                "        <timeSpan>\n" +
                                "            <startTime>2024-09-14T08:00:00Z</startTime>\n" +
                                "            <endTime>024-09-14T08:00:20Z</endTime>\n" +
                                "        </timeSpan>\n" +
                                "    </timeSpanList>\n" +
                                "    <maxResults>100</maxResults>\n" +
                                "    <searchResultPostion>0</searchResultPostion>\n" +
                                "    <metadataList>\n" +
                                "        <metadataDescriptor>//recordType.meta.std-cgi.com</metadataDescriptor>\n" +
                                "    </metadataList>\n" +
                                "</CMSearchDescription>", "UTF-8"
                );
                httpPost.setEntity(requestEntity);

                // 执行请求
                try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                    // 处理响应
                    int statusCode = response.getStatusLine().getStatusCode();
                    System.out.println("Status Code: " + statusCode);
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        String responseBody = EntityUtils.toString(entity, "UTF-8");
                        System.out.println("Response Body: " + responseBody);
                        return responseBody;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        return "空";
    }

    //
    public static Map<String, Object> convertXmlToJsonMap(String xml) {
        try {
            //创建 XmlMapper 对象
            XmlMapper xmlMapper = new XmlMapper();
            System.out.println("进行convertXmlToJsonMap方法");
            // 读取 XML 并将其转换为 JsonNode
            // 假设 xml 是一个 String 类型的 XML 数据
            byte[] bytes = xml.getBytes(StandardCharsets.UTF_8); // 显式指定 UTF-8 编码
//            byte[] bytes = xml.getBytes();
//            System.out.println(bytes);
            JsonNode node = xmlMapper.readTree(bytes);

            // 创建 ObjectMapper 对象
            ObjectMapper jsonMapper = new ObjectMapper();
            // 将 JsonNode 转换为 JSON 字符串
            String jsonString = jsonMapper.writeValueAsString(node);
//            System.out.println(jsonString);
            // 将 JSON 字符串转换为 Map
            return jsonMapper.readValue(jsonString, Map.class);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    public static String convertIpToNumeric(String ip) {
        String[] parts = ip.split("\\."); // 使用正则表达式split，以点分隔IP地址
        StringBuilder sb = new StringBuilder();
        for (String part : parts) {
            // Integer.parseInt将字符串转换为整数，然后toString转回字符串形式，format确保至少有3位数，不够的前面补0
            sb.append(String.format("%03d", Integer.parseInt(part)));
        }
        return sb.toString();
    }
    //
}
